package com.toocms.tab.base;

import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;

import com.blankj.utilcode.util.ActivityUtils;
import com.blankj.utilcode.util.ArrayUtils;
import com.blankj.utilcode.util.ObjectUtils;
import com.blankj.utilcode.util.ReflectUtils;
import com.blankj.utilcode.util.StringUtils;
import com.blankj.utilcode.util.ThreadUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.luck.picture.lib.basic.PictureSelector;
import com.luck.picture.lib.config.SelectMimeType;
import com.luck.picture.lib.config.SelectModeConfig;
import com.luck.picture.lib.entity.LocalMedia;
import com.luck.picture.lib.interfaces.OnResultCallbackListener;
import com.qmuiteam.qmui.arch.QMUIFragmentActivity;
import com.qmuiteam.qmui.widget.QMUITopBarLayout;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUIDialogAction;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.toocms.tab.R;
import com.toocms.tab.TooCMSApplication;
import com.toocms.tab.base.UIChangeLiveData.ParameterField;
import com.toocms.tab.binding.command.BindingConsumer;
import com.toocms.tab.bus.Messenger;
import com.toocms.tab.imageload.engine.CompressEngine;
import com.toocms.tab.imageload.engine.CropEngine;
import com.toocms.tab.imageload.engine.GlideEngine;
import com.toocms.tab.imageload.engine.SandboxEngine;
import com.toocms.tab.imageload.psui.PsUI;
import com.toocms.tab.widget.statusview.MultipleStatusView;
import com.umeng.analytics.MobclickAgent;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

/**
 * 用户交互页面
 * <p>
 * V基类
 *
 * @author Zero
 */
public abstract class BaseFragment<V extends ViewDataBinding, VM extends BaseViewModel> extends LifecycleFragment implements IBaseAction {

    protected V binding;
    protected VM viewModel;

    protected QMUITopBarLayout topBar;
    protected ConstraintLayout content;
    protected MultipleStatusView statusView;
    protected QMUITipDialog tipDialog;

    // ================================== 回调函数 ==================================

    protected abstract void onFragmentCreated();

    protected abstract @LayoutRes
    int getLayoutResId();

    public abstract int getVariableId();

    protected abstract void viewObserver();

    // 非最后一层子类传入V和VM需重写该回调方法
    protected VM getViewModel() {
        return null;
    }

    protected boolean isEnableHideSoftInput() {
        return true;
    }

    // ================================== 初始化 ==================================

    @Override
    protected View onCreateView() {
        View rootView = LayoutInflater.from(getActivity()).inflate(R.layout.base_root_view, null);
        topBar = rootView.findViewById(R.id.root_topbar);
        statusView = rootView.findViewById(R.id.root_status_view);
        topBar.addLeftBackImageButton().setOnClickListener(v -> finishFragment());
        content = rootView.findViewById(R.id.root_content);
        binding = DataBindingUtil.inflate(getLayoutInflater(), getLayoutResId(), (ViewGroup) rootView, false);
        content.addView(binding.getRoot());
        statusView.showContent();
        return rootView;
    }

    @Override
    protected void onViewCreated(@NonNull View rootView) {
        //初始化DataBinding和ViewModel
        initVVM();
        // 设置加载条为非全屏
        viewModel.resetShowContent();
        //注册ViewModel与View的契约事件回调逻辑
        registerUIChangeLiveDataCallBack();
        // 控制是否启用点击空白隐藏键盘
        getBaseActivity().setEnableHideSoftInput(isEnableHideSoftInput());
        //页面数据初始化方法
        onFragmentCreated();
        //页面事件监听的方法，一般用于ViewModel层转到View层的事件注册
        viewObserver();
        //注册RxBus
        viewModel.registerRxBus();
    }

    @Override
    public void onResume() {
        super.onResume();
        if (isEnableUmStatistics()) MobclickAgent.onPageStart(getClass().getSimpleName());
    }

    @Override
    public void onPause() {
        super.onPause();
        if (isEnableUmStatistics()) MobclickAgent.onPageEnd(getClass().getSimpleName());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Messenger.getDefault().unregister(viewModel);
        if (viewModel != null) {
            viewModel.removeRxBus();
        }
        if (binding != null) {
            binding.unbind();
        }
    }

    // 注入绑定
    private void initVVM() {
        viewModel = getViewModel();
        if (viewModel == null) {
            Class modelClass;
            Type type = getClass().getGenericSuperclass();
            if (type instanceof ParameterizedType) {
                modelClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[1];
            } else {
                //如果没有指定泛型参数，则默认使用BaseViewModel
                modelClass = BaseViewModel.class;
            }
            viewModel = (VM) createViewModel(this, modelClass);
        }
        binding.setVariable(getVariableId(), viewModel);
        //支持LiveData绑定xml，数据改变，UI自动会更新
        binding.setLifecycleOwner(this);
        //让ViewModel拥有View的生命周期感应
        getLifecycle().addObserver(viewModel);
        //注入RxLifecycle生命周期
        viewModel.injectLifecycleProvider(this);
    }

    public <T extends ViewModel> T createViewModel(Fragment fragment, Class<T> cls) {
        return new ViewModelProvider(fragment, ViewModelProvider.AndroidViewModelFactory.getInstance(TooCMSApplication.getInstance())).get(cls);
    }

    protected boolean isEnableUmStatistics() {
        return true;
    }

    // ============================== Action ===============================

    @Override
    public void showToast(String text) {
        ToastUtils.showShort(text);
    }

    @Override
    public void showToast(int resId) {
        ToastUtils.showShort(resId);
    }

    @Override
    public void showTip(@QMUITipDialog.Builder.IconType int iconType, CharSequence tipWord) {
        if (tipDialog == null) {
            tipDialog = new QMUITipDialog.Builder(getActivity())
                    .setIconType(iconType)
                    .setTipWord(tipWord)
                    .create();
        }
        if (!tipDialog.isShowing()) {
            tipDialog.show();
        }
    }

    @Override
    public void hideTip() {
        if (tipDialog != null) if (tipDialog.isShowing()) tipDialog.dismiss();
    }

    @Override
    public void showEditDialog(String title, String placeholder, int inputType, String actionStr, BindingConsumer<String> action) {
        QMUIDialog.EditTextDialogBuilder builder = new QMUIDialog.EditTextDialogBuilder(getContext());
        builder.setTitle(title)
                .setPlaceholder(placeholder)
                .setInputType(inputType)
                .addAction(actionStr, (qmuiDialog, i) -> {
                    action.call(builder.getEditText().getText().toString());
                    qmuiDialog.dismiss();
                }).show();
    }

    @Override
    public void showItemsDialog(String title, String[] items, DialogInterface.OnClickListener listener) {
        new QMUIDialog.MenuDialogBuilder(getContext())
                .setTitle(title)
                .addItems(items, listener)
                .show();
    }

    @Override
    public void showSingleActionDialog(String title, String message, String actionStr, QMUIDialogAction.ActionListener actionListener) {
        new QMUIDialog.MessageDialogBuilder(getContext())
                .setTitle(title)
                .setMessage(message)
                .addAction(actionStr, actionListener)
                .show();
    }

    @Override
    public void showDialog(String title, String message, String leftActionStr, QMUIDialogAction.ActionListener leftActionListener, String rightActionStr, QMUIDialogAction.ActionListener rightActionListener) {
        new QMUIDialog.MessageDialogBuilder(getContext())
                .setTitle(title)
                .setMessage(message)
                .addAction(leftActionStr, leftActionListener)
                .addAction(rightActionStr, rightActionListener)
                .show();
    }

    @Override
    public void showProgress() {
        if (viewModel.showContent) {
            if (statusView.getViewStatus() != MultipleStatusView.STATUS_LOADING)
                statusView.showLoading();
        } else {
            showTip(QMUITipDialog.Builder.ICON_TYPE_LOADING, null);
        }
    }

    @Override
    public void removeProgress() {
        if (statusView.getViewStatus() == MultipleStatusView.STATUS_LOADING)
            statusView.showContent();
        hideTip();
    }

    @Override
    public void showEmpty(String... tip) {
        statusView.showEmpty(ArrayUtils.isEmpty(tip) ? getString(R.string.base_empty_view_hint) : tip[0]);
    }

    @Override
    public void showFailed(String error, View.OnClickListener listener) {
        statusView.setOnRetryClickListener(listener);
        statusView.showError(StringUtils.isEmpty(error) ? getString(R.string.base_error_view_hint) : error);
    }

    @Override
    public void showNoNetwork(String tip, View.OnClickListener listener) {
        statusView.setOnRetryClickListener(listener);
        statusView.showNoNetwork(StringUtils.isEmpty(tip) ? getString(R.string.base_no_network_view_hint) : tip);
    }

    @Override
    public void showContent() {
        statusView.showContent();
    }

    @Override
    public void startActivity(Class<? extends Activity> clz) {
        ActivityUtils.startActivity(clz);
    }

    @Override
    public void startActivity(Class<? extends Activity> clz, @NonNull Bundle bundle) {
        ActivityUtils.startActivity(bundle, clz, R.anim.slide_in_right, R.anim.slide_out_left);
    }

    @Override
    public void finishActivity(Class<? extends Activity> clz) {
        ActivityUtils.finishActivity(clz);
    }

    @Override
    public void startSelectSignImageAty(OnResultCallbackListener<LocalMedia> listener, int... ratio) {
        int aspect_ratio_x = 1, aspect_ratio_y = 1;
        if (ratio != null && ratio.length != 0) {
            aspect_ratio_x = ratio[0];
            aspect_ratio_y = ratio[1];
        }
        startSelectSignAty(SelectMimeType.ofImage(), aspect_ratio_x, aspect_ratio_y, 120, 120, listener);
    }

    @Override
    public void startSelectSignVideoAty(OnResultCallbackListener<LocalMedia> listener) {
        startSelectSignAty(SelectMimeType.ofVideo(), 1, 1, 120, 120, listener);
    }

    @Override
    public void startSelectSignAllAty(OnResultCallbackListener<LocalMedia> listener) {
        startSelectSignAty(SelectMimeType.ofAll(), 1, 1, 120, 120, listener);
    }

    @Override
    public void startSelectSignAty(int chooseMode, int aspect_ratio_x, int aspect_ratio_y, int videoMaxSecond, int recordVideoSecond, OnResultCallbackListener<LocalMedia> listener) {
        PictureSelector.create(this)
                .openGallery(chooseMode)    // 扫描文件类型
                .setSelectorUIStyle(PsUI.createPsUI()) // 相册启动退出动画
                .setImageEngine(GlideEngine.createGlideEngine())   // 图片加载引擎
                .setCropEngine(CropEngine.createCropEngine(aspect_ratio_x, aspect_ratio_y))
                .setCompressEngine(CompressEngine.createCompressEngine())   // 压缩加载引擎
                .setSandboxFileEngine(SandboxEngine.createSandboxEngine())
                .isWithSelectVideoImage(true) // 图片和视频是否可以同选,只在ofAll模式下有效
                .setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)  // 相册Activity方向
                .isOriginalControl(false)  // 不显示原图控制按钮
                .setSelectionMode(SelectModeConfig.SINGLE)    // 单选
                .isDirectReturnSingle(true) // 裁剪之后直接返回
                .setFilterVideoMaxSecond(videoMaxSecond) // 显示多少秒以内的视频or音频
                .setRecordVideoMaxSecond(recordVideoSecond)  //  视频录制秒数
                .forResult(listener);   // 回调
    }

    @Override
    public void startSelectMultipleImageAty(List<LocalMedia> selectionMedia, int maxSelectNum, OnResultCallbackListener<LocalMedia> listener) {
        startSelectMultipleAty(SelectMimeType.ofImage(), selectionMedia, maxSelectNum, 120, 120, listener);
    }

    @Override
    public void startSelectMultipleVideoAty(List<LocalMedia> selectionMedia, int maxSelectNum, OnResultCallbackListener<LocalMedia> listener) {
        startSelectMultipleAty(SelectMimeType.ofVideo(), selectionMedia, maxSelectNum, 120, 120, listener);
    }

    @Override
    public void startSelectMultipleAllAty(List<LocalMedia> selectionMedia, int maxSelectNum, OnResultCallbackListener<LocalMedia> listener) {
        startSelectMultipleAty(SelectMimeType.ofAll(), selectionMedia, maxSelectNum, 120, 120, listener);
    }

    @Override
    public void startSelectMultipleAty(int chooseMode, List<LocalMedia> selectionMedia, int maxSelectNum, int videoMaxSecond, int recordVideoSecond, OnResultCallbackListener<LocalMedia> listener) {
        PictureSelector.create(this)
                .openGallery(chooseMode)    // 扫描文件类型
                .setSelectorUIStyle(PsUI.createPsUI()) // 相册启动退出动画
                .setImageEngine(GlideEngine.createGlideEngine())   // 图片加载引擎
                .setCompressEngine(CompressEngine.createCompressEngine())   // 压缩加载引擎
                .setSandboxFileEngine(SandboxEngine.createSandboxEngine())
                .isWithSelectVideoImage(true) // 图片和视频是否可以同选,只在ofAll模式下有效
                .setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)  // 相册Activity方向
                .isOriginalControl(false)  // 不显示原图控制按钮
                .setMaxSelectNum(maxSelectNum) // 最大选择数量
                .setSelectionMode(SelectModeConfig.MULTIPLE)    // 多选
                .setSelectedData(selectionMedia) //  传入已选数据
                .setFilterVideoMaxSecond(videoMaxSecond) // 显示多少秒以内的视频or音频
                .setRecordVideoMaxSecond(recordVideoSecond)  //  视频录制秒数
                .forResult(listener);   // 回调
    }

    @Override
    public void startFragment(Class<? extends BaseFragment> clz, boolean... isDestroyCurrent) {
        startFragment(clz, null, isDestroyCurrent);
    }

    @Override
    public void startFragment(Class<? extends BaseFragment> clz, Bundle bundle, boolean... isDestroyCurrent) {
        ObjectUtils.requireNonNull(clz);
        BaseFragment fragment = ReflectUtils.reflect(clz).newInstance().get();
        if (ObjectUtils.isNotEmpty(bundle)) fragment.setArguments(bundle);
        if ((!ArrayUtils.isEmpty(isDestroyCurrent) && isDestroyCurrent[0])) {
            startFragmentAndDestroyCurrent(fragment);
        } else {
            startFragment(fragment);
        }
    }

    @Override
    public void startFragmentForResult(Class<? extends BaseFragment> clz, int requestCode) {
        startFragmentForResult(clz, null, requestCode);
    }

    @Override
    public void startFragmentForResult(Class<? extends BaseFragment> clz, Bundle bundle, int requestCode) {
        ObjectUtils.requireNonNull(clz);
        BaseFragment fragment = ReflectUtils.reflect(clz).newInstance().get();
        if (ObjectUtils.isNotEmpty(bundle)) fragment.setArguments(bundle);
        startFragmentForResult(fragment, requestCode);
    }

    @Override
    public void finishFragment() {
        popBackStack();
    }

    @Override
    public void setFragmentResult(int resultCode, Intent data) {
        super.setFragmentResult(resultCode, data);
    }

    @Override
    public void popToFragment(Class<? extends BaseFragment> clz, boolean isIncludeSelf) {
        getBaseFragmentActivity().getContainerFragmentManager().popBackStackImmediate(clz.getSimpleName(), isIncludeSelf ? FragmentManager.POP_BACK_STACK_INCLUSIVE : 0);
    }

    @Override
    public void popDialogFragment(Class<? extends BaseDialogFragment> clz, Bundle bundle) {
        ObjectUtils.requireNonNull(clz);
        BaseDialogFragment dialogFragment = ReflectUtils.reflect(clz).newInstance().get();
        if (ObjectUtils.isNotEmpty(bundle)) dialogFragment.setArguments(bundle);
        dialogFragment.show(getChildFragmentManager(), dialogFragment.getClass().getSimpleName());
    }

    @Override
    protected void onFragmentResult(int requestCode, int resultCode, Intent data) {
        super.onFragmentResult(requestCode, resultCode, data);
    }

    // 注册ViewModel与View的契约UI回调事件
    protected void registerUIChangeLiveDataCallBack() {
        // 显示Tip
        viewModel.getUiChangeLiveData().getShowTipEvent().observe(this, params -> {
            int tipType = (int) params.get(ParameterField.TIP_TYPE);
            String tipWord = (String) params.get(ParameterField.TIP_TEXT);
            showTip(tipType, tipWord);
        });
        // 移除Tip
        viewModel.getUiChangeLiveData().getHideTipEvent().observe(this, v -> hideTip());
        // EditDialog
        viewModel.getUiChangeLiveData().getShowItemsDialogEvent().observe(this, params -> {
            String title = (String) params.get(ParameterField.DIALOG_TITLE);
            String[] items = (String[]) params.get(ParameterField.DIALOG_ITEMS);
            DialogInterface.OnClickListener listener = (DialogInterface.OnClickListener) params.get(ParameterField.DIALOG_ITEMS_LISTENER);
            showItemsDialog(title, items, listener);
        });
        // ItemDialog
        viewModel.getUiChangeLiveData().getShowEditDialogEvent().observe(this, params -> {
            String title = (String) params.get(ParameterField.DIALOG_TITLE);
            String placeholder = (String) params.get(ParameterField.DIALOG_PLACE_HOLDER);
            int inputType = (int) params.get(ParameterField.DIALOG_INPUT_TYPE);
            String actionText = (String) params.get(ParameterField.DIALOG_LEFT_ACTION_TEXT);
            BindingConsumer<String> consumer = (BindingConsumer<String>) params.get(ParameterField.DIALOG_LEFT_ACTION_LISTENER);
            showEditDialog(title, placeholder, inputType, actionText, consumer);
        });
        // SingleActionDialog
        viewModel.getUiChangeLiveData().getShowSingleActionDialogEvent().observe(this, params -> {
            String title = (String) params.get(ParameterField.DIALOG_TITLE);
            String message = (String) params.get(ParameterField.DIALOG_MESSAGE);
            String actionText = (String) params.get(ParameterField.DIALOG_LEFT_ACTION_TEXT);
            QMUIDialogAction.ActionListener actionListener = (QMUIDialogAction.ActionListener) params.get(ParameterField.DIALOG_LEFT_ACTION_LISTENER);
            showSingleActionDialog(title, message, actionText, actionListener);
        });
        // Dialog
        viewModel.getUiChangeLiveData().getShowDialogEvent().observe(this, params -> {
            String title = (String) params.get(ParameterField.DIALOG_TITLE);
            String message = (String) params.get(ParameterField.DIALOG_MESSAGE);
            String leftActionText = (String) params.get(ParameterField.DIALOG_LEFT_ACTION_TEXT);
            QMUIDialogAction.ActionListener leftActionListener = (QMUIDialogAction.ActionListener) params.get(ParameterField.DIALOG_LEFT_ACTION_LISTENER);
            String rightActionText = (String) params.get(ParameterField.DIALOG_RIGHT_ACTION_TEXT);
            QMUIDialogAction.ActionListener rightActionListener = (QMUIDialogAction.ActionListener) params.get(ParameterField.DIALOG_RIGHT_ACTION_LISTENER);
            showDialog(title, message, leftActionText, leftActionListener, rightActionText, rightActionListener);
        });
        // 显示加载条
        viewModel.getUiChangeLiveData().getShowProgressEvent().observe(this, v -> showProgress());
        // 移除加载条
        viewModel.getUiChangeLiveData().getRemoveProgressEvent().observe(this, v -> removeProgress());
        // 显示空视图
        viewModel.getUiChangeLiveData().getShowEmptyEvent().observe(this, this::showEmpty);
        // 显示错误视图
        viewModel.getUiChangeLiveData().getShowFailedEvent().observe(this, params -> {
            String error = (String) params.get(ParameterField.ERROR_TEXT);
            View.OnClickListener listener = (View.OnClickListener) params.get(ParameterField.ERROR_LISTENER);
            showFailed(error, listener);
        });
        viewModel.getUiChangeLiveData().getShowNoNetworkEvent().observe(this, params -> {
            String error = (String) params.get(ParameterField.ERROR_TEXT);
            View.OnClickListener listener = (View.OnClickListener) params.get(ParameterField.ERROR_LISTENER);
            showNoNetwork(error, listener);
        });
        viewModel.getUiChangeLiveData().getShowContentEvent().observe(this, v -> showContent());
        // 跳转单选图片
        viewModel.getUiChangeLiveData().getStartSelectSignAtyEvent().observe(this, params -> {
            int chooseMode = (int) params.get(ParameterField.SELECT_PICTURE_MODE);
            int aspect_ratio_x = (int) params.get(ParameterField.SELECT_PICTURE_RATIO_X);
            int aspect_ratio_y = (int) params.get(ParameterField.SELECT_PICTURE_RATIO_Y);
            int videoMaxSecond = (int) params.get(ParameterField.SELECT_PICTURE_VIDEO_MAX_SECOND);
            int recordVideoSecond = (int) params.get(ParameterField.SELECT_PICTURE_RECORD_VIDEO_SECOND);
            OnResultCallbackListener listener = (OnResultCallbackListener) params.get(ParameterField.SELECT_PICTURE_CALLBACK_LISTENER);
            startSelectSignAty(chooseMode, aspect_ratio_x, aspect_ratio_y, videoMaxSecond, recordVideoSecond, listener);
        });
        // 跳转多选图片
        viewModel.getUiChangeLiveData().getStartSelectMultipleAtyEvent().observe(this, params -> {
            int chooseMode = (int) params.get(ParameterField.SELECT_PICTURE_MODE);
            List<LocalMedia> selectionMedia = (List<LocalMedia>) params.get(ParameterField.SELECT_PICTURE_SELECTION_MEDIA);
            int maxSelectNum = (int) params.get(ParameterField.SELECT_PICTURE_MAX_SELECT_NUM);
            int videoMaxSecond = (int) params.get(ParameterField.SELECT_PICTURE_VIDEO_MAX_SECOND);
            int recordVideoSecond = (int) params.get(ParameterField.SELECT_PICTURE_RECORD_VIDEO_SECOND);
            OnResultCallbackListener listener = (OnResultCallbackListener) params.get(ParameterField.SELECT_PICTURE_CALLBACK_LISTENER);
            startSelectMultipleAty(chooseMode, selectionMedia, maxSelectNum, videoMaxSecond, recordVideoSecond, listener);
        });
        // 启动Fragment
        viewModel.getUiChangeLiveData().getStartFragmentEvent().observe(this, params -> {
            Class<? extends BaseFragment> clz = (Class<? extends BaseFragment>) params.get(ParameterField.FRAGMENT);
            Bundle bundle = (Bundle) params.get(ParameterField.BUNDLE);
            boolean[] isDestroyCurrent = (boolean[]) params.get(ParameterField.DESTROY_CURRENT);
            startFragment(clz, bundle, isDestroyCurrent);
        });
        // 启动Fragment并等待返回值
        viewModel.getUiChangeLiveData().getStartFragmentForResultEvent().observe(this, params -> {
            Class<? extends BaseFragment> clz = (Class<? extends BaseFragment>) params.get(ParameterField.FRAGMENT);
            Bundle bundle = (Bundle) params.get(ParameterField.BUNDLE);
            int requestCode = (int) params.get(ParameterField.REQUEST_CODE);
            startFragmentForResult(clz, bundle, requestCode);
        });
        // 关闭Fragment
        viewModel.getUiChangeLiveData().getFinishFragmentEvent().observe(this, v -> ThreadUtils.runOnUiThreadDelayed(this::finishFragment, 100));
        // 设置Fragment返回结果
        viewModel.getUiChangeLiveData().getSetFragmentResultEvent().observe(this, params -> {
            int resultCode = (int) params.get(ParameterField.RESULT_CODE);
            Intent data = (Intent) params.get(ParameterField.INTENT);
            setFragmentResult(resultCode, data);
        });
        // 返回至指定Fragment
        viewModel.getUiChangeLiveData().getPopToFragmentEvent().observe(this, params -> {
            Class<? extends BaseFragment> clz = (Class<? extends BaseFragment>) params.get(ParameterField.FRAGMENT);
            boolean isIncludeSelf = (boolean) params.get(ParameterField.IS_INCLUDE_SELF);
            popToFragment(clz, isIncludeSelf);
        });
        viewModel.getUiChangeLiveData().getPopDialogEvent().observe(this, params -> {
            Class<? extends BaseDialogFragment> clz = (Class<? extends BaseDialogFragment>) params.get(ParameterField.DIALOG_FRAGMENT);
            Bundle bundle = (Bundle) params.get(ParameterField.BUNDLE);
            popDialogFragment(clz, bundle);
        });
    }

    //刷新布局
    public void refreshLayout() {
        if (viewModel != null) {
            binding.setVariable(getVariableId(), viewModel);
        }
    }

    protected BaseActivity getBaseActivity() {
        QMUIFragmentActivity activity = getBaseFragmentActivity();
        if (activity instanceof BaseActivity) {
            return (BaseActivity) activity;
        }
        return null;
    }
}
